package com.ruoyi.system.utils;

import com.ruoyi.system.protocol.IDynamicCacheService;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.metrics.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Component
public class RetrievalUtil {

    @Autowired
    private IDynamicCacheService dynamicCache;

    /**
     * 获取总页数
     * @param total
     * @param pageSize
     * @return
     */
    public long getPageCount(long total, int pageSize){
        if (pageSize == 0) {
            return 0L;
        }
        long pages = total / pageSize;
        if (total % pageSize != 0) {
            pages++;
        }
        return pages;
    }

    public String conversionRetrievalQuery(String queryStr) {
        Pattern fieldValuePattern = Pattern.compile(
                "\\$(.*?)(\\.|\\:)", Pattern.DOTALL);
        Matcher matcher = fieldValuePattern.matcher(queryStr);
        HashMap<String, String> conversionField = new HashMap<>();
        while (matcher.find()){
            String keyQuery = matcher.group(0);  //$标题:
            String key = matcher.group(1); //标题
            conversionField.put(keyQuery, replaceRetrievalFieldForward(key)+keyQuery.substring(keyQuery.length()-1));
        }
        for(String key: conversionField.keySet()){
            queryStr = queryStr.replace(key, conversionField.get(key));
        }
        return queryStr;
    }

    /**
     * 替换字段
     *
     * @param key
     * @return
     */
    public String replaceRetrievalFieldForward(String key) {
        if(key==null){
            return "";
        }else if (key.equals("id") || key.equals("type") || key.equals("typeId")) {
            return key;
        } else if (key.equals("create_time")) {
            return "dateIS_create_time";
        } else if (key.equals("update_time")) {
            return "dateIS_update_time";
        } else if (key.equals("classEn")) {
            return "stringIS_classEn";
        } else if (key.equals("classZh")) {
            return "stringIS_classZh";
        } else if (key.equals("dbEn")) {
            return "stringIS_dbEn";
        } else if (key.equals("dbZh")) {
            return "stringIS_dbZh";
        } else if (key.equals("create_user_id")) {
            return "intIS_create_user_id";
        } else if (key.equals("create_user_name")) {
            return "stringIS_create_user_name";
        } else if (key.equals("update_user_id")) {
            return "intIS_update_user_id";
        } else if (key.equals("update_user_name")) {
            return "stringIS_update_user_name";
        } else if (key.equals("create_dept_id")) {
            return "intIS_create_dept_id";
        } else if (key.equals("create_dept_name")) {
            return "stringIS_create_dept_name";
        } else if (key.equals("status")) {
            return "intIS_status";
        } else {
            return (String) dynamicCache.getFiledForward(key);
        }
    }


    /**
     * 替换字段
     *
     * @param key
     * @return
     */
    public String replaceRetrievalFieldReverse(String key) {
        if(key==null){
            return "";
        }else if (key.equals("id") || key.equals("type") || key.equals("typeId")) {
            return key;
        } else if (key.equals("dateIS_create_time")) {
            return "create_time";
        } else if (key.equals("dateIS_update_time")) {
            return "update_time";
        } else if (key.equals("stringIS_classEn")) {
            return "classEn";
        } else if (key.equals("stringIS_classZh")) {
            return "classZh";
        } else if (key.equals("stringIS_dbEn")) {
            return "dbEn";
        } else if (key.equals("stringIS_dbZh")) {
            return "dbZh";
        } else if (key.equals("intIS_create_user_id")) {
            return "create_user_id";
        } else if (key.equals("stringIS_create_user_name")) {
            return "create_user_name";
        } else if (key.equals("intIS_update_user_id")) {
            return "update_user_id";
        } else if (key.equals("stringIS_update_user_name")) {
            return "update_user_name";
        } else if (key.equals("intIS_create_dept_id")) {
            return "create_dept_id";
        } else if (key.equals("stringIS_create_dept_name")) {
            return "create_dept_name";
        } else if (key.equals("intIS_status")) {
            return "status";
        }else {
            String zhuanhuaKey = key.substring(key.indexOf("_") > 0 ? key.indexOf("_") + 1 : 0);
            return zhuanhuaKey;
        }
    }

    /**
     * 列表替换字段  string_title -> title
     * @param sourceAsMap 结果map
     */
    public Map<String, Object> fieldReplaceList(Map<String, Object> sourceAsMap){
        Map<String, Object> temp_sourceAsMap = new HashMap<>();
        sourceAsMap.forEach((key,val)->{
//            String filedReverseNameEn = dynamicCache.getFiledReverse(key);
            String filedReverseNameEn = this.replaceRetrievalFieldReverse(key);
            temp_sourceAsMap.put(filedReverseNameEn, val);
        });
        return temp_sourceAsMap;
    }

    /**
     * Aggregation格式化聚合字段结果
     * @param aggregation
     * @return
     */
    public Map<String,Object> formatAggregationData(Aggregation aggregation){
        Map<String, Object> map = new LinkedHashMap<>();
        if(aggregation!=null){
            String type = aggregation.getType();
            if("sum".equals(type)){
                Sum sum = (Sum)aggregation;
                map.put(aggregation.getName(),sum.getValue());
            }else if("max".equals(type)){
                Max max = (Max)aggregation;
                map.put(aggregation.getName(),max.getValue());
            }else if("min".equals(type)){
                Min min = (Min)aggregation;
                map.put(aggregation.getName(),min.getValue());
            }else if("avg".equals(type)){
                Avg avg = (Avg)aggregation;
                map.put(aggregation.getName(),avg.getValue());
            }else if("cardinality".equals(type)){
                Cardinality cardinality = (Cardinality)aggregation;
                map.put(aggregation.getName(),cardinality.getValue());
            }else if("date_histogram".equals(type)){
                Terms histogram = (Terms) aggregation;
                map.put(aggregation.getName(),formatTermsData(histogram));
            }else if(type.contains("terms")){
                Terms term = (Terms)aggregation;
                map.put(aggregation.getName(),formatTermsData(term));
            }else{
                map.put(aggregation.getName(), aggregation);
            }
        }
        return map;
    }

    /**
     * Terms格式化聚合字段结果
     * @param ：terms
     * @return
     */
    public  Map<String,Object> formatTermsData(Terms terms){
        Map<String, Object> map = new LinkedHashMap<>();
        for (Terms.Bucket b : terms.getBuckets()) {
            //val 特定字段、二次聚合使用
            Map<String, Object> val = new LinkedHashMap<>();
            String key = b.getKey().toString();
            List<Aggregation> aggregations = b.getAggregations().asList();
            if(aggregations.size()>0){
                val.put("count", b.getDocCount());
                for(Aggregation aggregation : aggregations){
                    val.putAll(formatAggregationData(aggregation));
                }
                map.put(key, val);
                val=null;
            }else{
                if(val.size()>0){
                    map.put(key, val);
                }else{
                    map.put(key, b.getDocCount());
                }
            }
            aggregations=null;
        }
        return map;
    }
}
